package org.spdata.tsdb.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;

import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.Binary;
import org.bson.types.ObjectId;
import org.spdata.tsdb.dao.SnapshotDAO;
import org.spdata.tsdb.entity.Snapshot;
import org.spdata.tsdb.entity.Snapshot.Type;
import org.springframework.stereotype.Repository;

import com.mongodb.BasicDBObject;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;


@Repository(value="snapshot")
public class SnapshotDAOImpl extends BaseDAOImpl<Snapshot> implements SnapshotDAO {
	
	
	@PostConstruct
	public void init() {
		long count = super.getCollection().count();
		if(count==0L) {
			super.getCollection().dropIndexes();
			BasicDBObject indexes = new BasicDBObject("time",1);
			indexes.append("index", 1);
			indexes.append("_id", 1);
			super.getCollection().createIndex(indexes);
			
			indexes = new BasicDBObject("parent",1);
			indexes.append("index", 1);
			super.getCollection().createIndex(indexes);
		}
	}

	@Override
	public void deleteTimeoutSnapshots(Date before) {
		super.remove(Filters.lt("time", before));
		
	}
	
	public boolean existFullSnapshot() {
		long count =  super.count(Filters.eq("type",Type.full.toString()));
		return count>0;
	}
	
	@Override
	public  List<Snapshot> findLastFullSnapshot() {
		Snapshot snapshot= super.findOne(Filters.eq("type", Type.full.toString()), new BasicDBObject("time",-1));
		if(snapshot!=null) {
			List<Snapshot> ss = super.findOrderList(Filters.eq("parent",snapshot.getId()),Sorts.ascending("index"));
			List<Snapshot> result = new ArrayList<Snapshot>();
			result.add(snapshot);	
			if(ss!=null)
				result.addAll(ss);
			return result;
		}else
			return null;
	}

	@Override
	public List<Snapshot> findAdditionSnapshots(Date after,int size) {
		BasicDBObject orderBy = new BasicDBObject("time",1);
		orderBy.append("index", 1);
		List<Snapshot> list = super.nextPage(Filters.gte("time", after), orderBy, size, null);
		return list;
	}
	
	@Override
	public List<Snapshot> nextPageSnapshots(ObjectId after, int size) {
		BasicDBObject orderBy = new BasicDBObject("time",1);
		orderBy.append("index", 1);
		Bson startFrom = Filters.gt("_id", after);
		List<Snapshot> list = super.nextPage(null, orderBy, size, startFrom);
		return list;
	}


	@Override
	protected Snapshot readEntityFromDocument(Document doc) {
		ObjectId id = doc.getObjectId("_id");
		Date time = doc.getDate("time");
		String typeName = doc.getString("type");
		if(typeName==null) {
			throw new RuntimeException("快照类型不能为空");
		}
		Type type = Type.valueOf(doc.getString("type"));
		Binary data = (Binary) doc.get("data");
		int index  = doc.getInteger("index", 0);
		ObjectId parent = doc.getObjectId("parent");
		Snapshot ss = new Snapshot();
		ss.setId(id);
		ss.setTime(time);
		ss.setType(type);
		ss.setData(data.getData());
		ss.setIndex(index);
		ss.setParent(parent);
		return ss;
	}

	
	
}
